package com.miaosha.serivce.impl;

import com.miaosha.mapper.OrderMapper;
import com.miaosha.mapper.StocKMapper;
import com.miaosha.mapper.UserMapper;
import com.miaosha.pojo.Order;
import com.miaosha.pojo.Stock;
import com.miaosha.pojo.User;
import com.miaosha.serivce.OrderSerivce;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@Transactional
public class OrderSerivceimpl implements OrderSerivce {

     @Autowired
     private StocKMapper stocKMapper;

     @Autowired
     private OrderMapper orderMapper;

     @Autowired
     private UserMapper userMapper;

     @Autowired
     private StringRedisTemplate redisTemplate;

    @Override
    public  int kill(Integer id) {
         //redis 缓存
        //判断当前商品在缓存中不 不在秒杀活动中
        //     redis  执行  set kill1 1 ex 8   键值 kill+1     kill+id
      if(!redisTemplate.hasKey("kill"+id)){
          System.out.println("该商品秒杀活动失效了");
          throw new RuntimeException("该商品秒杀活动失效了！");
      }
        //检验库存
        Stock stock = checjStock(id);
        //更新库存
        updateSale(stock);
        //创建订单
      return  crateOrder(stock);

    }

    @Override
    public String getMd5(Integer id, Integer userId) {
         //验证userid 存在用户消息
        User user=userMapper.findByID(userId);
        if(user==null){
            throw  new  RuntimeException("用户不存在");
        }
        log.info("用户消息:"+user.toString());
        //验证id  存在商品信息
       Stock stock= stocKMapper.findByID(id);
        if (stock==null) {
            throw new RuntimeException("商品不存在");
        }
        log.info("商品信息:"+stock.toString());
         //生成key
        String hashKey ="KEY_"+userId+"_"+id;
        //生成 md5 密
        String md5DigestAsHex = DigestUtils.md5DigestAsHex((userId + id + "").getBytes());
        //在redis 数据库中 添加我们生成好的键值对  并且设置相应的时长                 TimeUnit.SECONDS :秒
        redisTemplate.opsForValue().set(hashKey,md5DigestAsHex,6000, TimeUnit.SECONDS);
        log.info("向redis插入:[][]"+hashKey);
        return md5DigestAsHex;
    }

    /**
     *  添加了md5
     *
     * @param id
     * @param userId
     * @param md5
     * @return
     */
    @Override
    public int kill(Integer id, Integer userId, String md5) {
/*        //redis 缓存
        //判断当前商品在缓存中不 不在秒杀活动中
        //     redis  执行  set kill1 1 ex 8   键值 kill+1     kill+id
        if(!redisTemplate.hasKey("kill"+id)){
            System.out.println("该商品秒杀活动失效了");
            throw new RuntimeException("该商品秒杀活动失效了！");
        }*/
        String hashKey ="KEY_"+userId+"_"+id;
         //判断我们生成的md5密 去缓存里面比较
        if(md5==null){throw new RuntimeException("携带签名不合法！");}
        if (!redisTemplate.opsForValue().get(hashKey).equals(md5)) {
             throw new RuntimeException("当前请求数据不合法！");
        }

        //检验库存
        Stock stock = checjStock(id);
        //更新库存
        updateSale(stock);
        //创建订单
        return  crateOrder(stock);
    }


    /**
     *  添加了md5+单用户的频率限制
     *
     * @param id
     * @param userId
     * @param md5
     * @return
     */
    @Override
    public int killUserMmilk(Integer id, Integer userId, String md5) {
/*        //redis 缓存
        //判断当前商品在缓存中不 不在秒杀活动中
        //     redis  执行  set kill1 1 ex 8   键值 kill+1     kill+id
        if(!redisTemplate.hasKey("kill"+id)){
            System.out.println("该商品秒杀活动失效了");
            throw new RuntimeException("该商品秒杀活动失效了！");
        }*/
        String hashKey ="KEY_"+userId+"_"+id;
        //判断我们生成的md5密 去缓存里面比较
        if(md5==null){throw new RuntimeException("携带签名不合法！");}
        if (!redisTemplate.opsForValue().get(hashKey).equals(md5)) {
            throw new RuntimeException("当前请求数据不合法！");
        }

        //检验库存
        Stock stock = checjStock(id);
        //更新库存
        updateSale(stock);
        //创建订单
        return  crateOrder(stock);
    }

    //检验库存
    private Stock checjStock(Integer id){
        Stock stock = stocKMapper.checkStock(id);
        if(stock.getSale().equals(stock.getCount())){
            throw  new RuntimeException("库存不足");
        }
        return stock;
    }

    //扣除库存
    private  void updateSale(Stock stock){
        stock.setSale(stock.getSale()+1);
        int i = stocKMapper.updateSale(stock);
        if(i==0){
             throw  new RuntimeException("抢购失败,请重试!!");
        }
    }
    //创建订单
    private Integer crateOrder(Stock stock){
        Order order = new Order();
        order.setSid(stock.getId());order.setName(stock.getName());order.setCreateTime(new Date());
        orderMapper.saveOrder(order);
        return order.getId();
    }
}
